using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using System.IO;
using CakeAnimation;

namespace CharacterAnimationEditor
{


    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class MainEditor
    {
        public AnimationControlGUI m_ControlGUI;
        public PlayGUI m_PlayGui;
        public OnionGUI m_OnionGui;
        public CurveGUI m_CurveGui;

        public TimelineGui m_Timeline;


        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        public void LoadContent(Context context)
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            context.SpriteBatch = new SpriteBatch(context.GD);



            context.Font = context.Content.Load<SpriteFont>("Arial");
            context.FontBig = context.Content.Load<SpriteFont>("ArialBig");
            context.PrevKeyState = Keyboard.GetState();
            context.PrevMouseState = Mouse.GetState();

            m_Timeline = new TimelineGui(context);

            Skeleton s = new Skeleton(context.AnimationContext, "SkeletonRig.txt");
            List<KeyFrame> kfs = new List<KeyFrame>();
            kfs.Add(new KeyFrame(context.AnimationContext, 0.0f, s));
            context.Animation = new Animation("Unnamed", kfs);
            context.SetCurrentKeyFrame( context.Animation.m_Keyframes[0]);


            m_ControlGUI = new AnimationControlGUI(context);
            m_PlayGui = new PlayGUI(context);
            m_OnionGui = new OnionGUI(context);
            m_CurveGui = new CurveGUI(context);
        }

        


        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public void Update(Context context)
        {

            context.UpdateInputState();



            m_ControlGUI.Update(context);

            m_Timeline.Update(context);
            context.CurrentKeyFrame.Pose.RootBone.UpdateTransform();

            m_PlayGui.Update(context);
            m_OnionGui.Update(context);
        }

        public static float LerpAngle(float start, float end, float scale)
        {
            start = MathHelper.WrapAngle(start);
            end = MathHelper.WrapAngle(end);
            float delta = end - start;

            // If delta is not the shortest way, travel in the opposite direction  
            if (delta > MathHelper.Pi)
            {
                return (MathHelper.WrapAngle(start - (MathHelper.TwoPi - delta) * scale));
            }
            else if (delta < -MathHelper.Pi)
            {
                return (MathHelper.WrapAngle(start + (MathHelper.TwoPi + delta) * scale));
            }

            // No special case needed  
            return (start + delta * scale);
        }

        private Vector2 ParseVector2(string p)
        {
            return new Vector2(float.Parse(p.Split()[0]), float.Parse(p.Split()[1]));
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public void Draw(Context context)
        {
            context.GD.Clear(Color.White);


            context.SpriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);

            Texture2D bg = context.Content.Load<Texture2D>("GroundBG");

            context.SpriteBatch.Draw(
                bg,
                Vector2.Zero,
                null,
                Color.White,
                0.0f,
                Vector2.Zero,
                context.GetWindowScale(),
                SpriteEffects.None,
                1.0f
                );

            m_ControlGUI.Draw(context);
            m_PlayGui.Draw(context);
            m_OnionGui.Draw(context);
            m_CurveGui.Draw(context);

            m_Timeline.Draw(context);

            context.SpriteBatch.End();

        }
    }
}
